import re
import time
from flask import request
from flask_restful import abort
from flask_login import current_user, login_user
from funcy import project
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.exc import IntegrityError
from funcy import partial

from redash import models, limiter
from redash.permissions import (
    require_admin,
)
from redash.handlers.base import (
    BaseResource,
    require_fields,
    get_object_or_404,
    paginate,
    order_results as _order_results,
)

from redash.authentication.account import (
    invite_link_for_user,
    send_invite_email,
    send_password_reset_email,
    send_verify_email,
)
from redash.settings import parse_boolean
from redash import settings

class WorkflowResource(BaseResource):
    def post(self):
        req = request.get_json(force=True)
        bill = req["bill"]
        billid = req["billid"]
        billtype = req["billtype"]
        next_type = req["next_type"]
        message = req["message"] if "message" in req else "<div>同意</div>"
        userid = req["userid"]
        billdate = req["billdate"]
        orgunitid = req["orgunitid"] if "orgunitid" in req else 0
        checkuserids = req["checkuserids"] if "checkuserids" in req else "0"
        warnsealuser=req["warnsealuser"] if "warnsealuser" in req else ""
        result = models.Workflow.workflowcheck(bill,billid,billtype,next_type,message,userid,billdate,orgunitid,self.current_org.id,checkuserids,warnsealuser)
        models.db.session.commit()
        return result[0]
    
class WorkflowUserResource(BaseResource):
    def post(self):
        req = request.get_json(force=True)
        bill = req["bill"]
        billid = req["billid"]
        billtype = req["billtype"]
        orgunitid = req["orgunitid"] if "orgunitid" in req else 0
        result = models.Workflow.workflowuser(bill,billid,billtype,orgunitid,self.current_org.id)
        models.db.session.commit()
        return result[0]

class WorkfloweditResource(BaseResource):
    def get(self,bill,billtype,billid,userid):
        result = models.Workflow.workflowedit(bill,billtype,billid,userid,self.current_org.id)
        return result[0]

class WorkflowmessageResource(BaseResource):
    def get(self, bill, billid,bill_type,orgunitid):
        result = models.Workflow.workflowmessage(bill, billid,bill_type,orgunitid)
        return result[0]

class WorkflowNewResource(BaseResource):
    def get(self):
        result = models.Workflow.get_id()
        return result[0]

    @require_admin
    def post(self):
        req = request.get_json(force=True)
        require_fields(req, ("bill_enum","name"))

        workflow = models.Workflow(
        id=req["id"],
        org=self.current_org,
        userid=req["userid"],
        name = req["name"],
        orgunitid  = req["orgunitid"],
        bill_enum = req["bill_enum"],
        bill_type = req["bill_type"],
        is_active = req["is_active"],
        )
        try:
            models.db.session.add(workflow)
            models.db.session.commit()
        except IntegrityError as e:
            if "name" in str(e):
                abort(400, message="编号已存在.")
            abort(500)


class WorkflowUpdateResource(BaseResource):
    def get(self, workflow_id):
        result = models.Workflow.get_by_id(workflow_id)
        return result.to_dict()

    @require_admin
    def post(self, workflow_id):
        req = request.get_json(force=True)
        require_fields(req, ("bill_enum","name"))

        workflow = models.Workflow.get_by_id(workflow_id)
        params = dict(bill_enum = req["bill_enum"],
                name=req["name"],bill_type=req["bill_type"],
                orgunitid  = req["orgunitid"],is_active=req["is_active"])
        try:
            self.update_model(workflow, params)
            models.db.session.commit()
        except IntegrityError as e:
            if "name" in str(e):
                abort(400, message="名称已存在.")
            abort(500)

class WorkflowUCopyResource(BaseResource):
    @require_admin
    def post(self, workflow_id,userid):
        strsql="""DO
                $do$
                declare  
                    v_workflowid integer; 
                BEGIN
                select nextval('workflow_id_seq'::regclass) into v_workflowid;
                insert into public.workflow(id,org_id,updated_at,created_at,userid,name,bill_enum,bill_type,is_active,orgunitid)
                select v_workflowid,org_id,now(),now(),"""+userid+""",name || '-复制',bill_enum,bill_type,is_active,0 from workflow where id="""+workflow_id+""";

                insert into public.workflow_transition(org_id,updated_at,created_at,userid,workflowid,workflow_stateid,next_type,next_workflow_stateid,
                allow_user,allow_group,allow_col,condition)
                select org_id,updated_at,created_at,"""+userid+""",v_workflowid,workflow_stateid,next_type,next_workflow_stateid,
                allow_user,allow_group,allow_col,condition from public.workflow_transition where workflowid="""+workflow_id+""";

                END
                $do$;"""
        models.db.session.execute(strsql)
        models.db.session.commit()

class WorkflowUpdatedeleteResource(BaseResource):
    @require_admin
    def post(self, workflow_id):
        workflow =  models.Workflow.get_by_id(workflow_id)
        workflow_transition = models.Workflow_transition.get_by_workflowid(workflow_id)
        models.db.session.delete(workflow_transition)
        models.db.session.delete(workflow)
        models.db.session.commit()

class WorkflowListResource(BaseResource):
    def post(self):
        req = request.get_json(force=True)
        page = req["page"]
        page_size = req["pagesize"]
        name = req["name"] if "name" in req else ""
        bill_enum = req["bill_enum"] if "bill_enum" in req else ""
        bill_type = str(req["bill_type"]) if "bill_type" in req else ""
        strwhere ="t1.org_id=" +str(self.current_org.id)
        if name !='' :
            strwhere = strwhere + " and t1.name like '%"+name+"%'"
        if bill_enum !='' :
            strwhere = strwhere + " and  t1.bill_enum ='"+bill_enum+"'"
        if bill_type !='' :
            strwhere = strwhere + " and  t1.bill_type ='"+bill_type+"'"
        strgetfield ="""  t1.*,case when t1.is_active then '已启用'  else '已停用' end strstatus,
            t4.name as billname,COALESCE(t5.name,'全部') as orgunitname """

        tblname = """ public.workflow t1  left join public.tabletype t4 on t1.bill_enum =t4.code and t1.bill_type=t4.type
            left join public.orgunit t5 on t1.orgunitid=t5.id """
        orderfield ="t1.id"
        result = models.ContractApply.get_pagequery(tblname,strgetfield,orderfield,page_size,page,0,strwhere)
        return result[0]

class WorkflowcheckListResource(BaseResource):
    def post(self):
        req = request.get_json(force=True)
        page = req["page"]
        page_size = req["pagesize"]
        statename = req["statename"]
        seltype = req["seltype"] #1 待审核-,2 已审核
        bill_enum = req["bill_enum"]
        userid = str(req["userid"])

        strwhere =" 1=1 "
        if bill_enum !='' :
            strwhere = strwhere + " and AA.bill_enum = '"+bill_enum+"'"
        if statename !='' :
            strwhere = strwhere + " and t4.name like '%"+statename+"%'"

        strgetfield ="""  AA.*,t3.name as tablename,t4.name as statename,AB.code,to_char(AB.bill_date,'YYYY-MM-DD')  bill_dateformat,AB.billstatus,
         AB.name """

        tblname = """  (select t1.id,t1.bill_enum,t1.billid,t1.bill_type,t1.workflow_stateid
                    from workflow_bill_state t1 where t1.is_active=true  and
                    ('""" + userid + """' = ANY(t1.allow_user) or t1.allow_group && (select groups from users where id='""" + userid + """'))) AA
                    inner join tabletype t3 on AA.bill_enum=t3.code
                    left join workflow_state t4 on AA.workflow_stateid=t4.id inner join
                    (select 'contractapply' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractapply union all
                        select 'contracts' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contracts union all
                        select 'contractseal' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractseal union all
                        select 'contractrecord' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractrecord  union all
                        select 'contractchange' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractchange union all
                        select 'contractprogress' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractprogress  union all
                        select 'contractsettle' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractsettle union all
                        select 'contractstop' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractstop union all
                        select 'contractfinish' as tablename,id,code,name,bill_date,status as billstatus,org_id,userid from  public.contractfinish) AB
                        on AA.bill_enum=AB.tablename and AA.billid=AB.id and AB.org_id=""" +str(self.current_org.id)
        if seltype == "2" :
            tblname = """ (select t1.*from public.workflow_action t1 where t1.status in(1,2,3) and
                     t1.completed_by='""" + userid + """') AA
                    inner join tabletype t3 on AA.bill_enum=t3.code
                    left join workflow_state t4 on AA.workflow_stateid=t4.id  inner join
                    (select 'contractapply' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractapply union all
                        select 'contracts' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contracts union all
                        select 'contractseal' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractseal union all
                        select 'contractrecord' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractrecord  union all
                        select 'contractchange' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractchange union all
                        select 'contractprogress' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractprogress  union all
                        select 'contractsettle' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractsettle union all
                        select 'contractstop' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractstop union all
                        select 'contractfinish' as tablename,id,code,name,bill_date,status as billstatus,org_id from  public.contractfinish) AB
                        on AA.bill_enum=AB.tablename and AA.billid=AB.id and AB.org_id=""" +str(self.current_org.id)

        orderfield ="AA.id"
        result = models.ContractApply.get_pagequery(tblname,strgetfield,orderfield,page_size,page,0,strwhere)
        return result[0]

class WorkflowcheckmessagResource(BaseResource):
    def post(self):
        req = request.get_json(force=True)
        billid = req["billid"]
        bill = req["bill"]
        typeid = req["typeid"]#0-审核批注信息,1审签表查询
        result = models.Workflow.getworkflowmessage(bill,billid,typeid,self.current_org.id)
        return result[0]
